package cn.study.luckyapp.server;

import cm.study.config.util.AssertUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.study.luckyapp.activity.command.ActivityAddCmdExe;
import cn.study.luckyapp.activity.command.ActivityUpdateCmdExe;
import cn.study.luckyapp.activity.query.ActivityListByParamQueryExe;
import cn.study.luckyapp.activityrule.command.ActivityRuleAddCmdExe;
import cn.study.luckyapp.activityrule.command.ActivityRuleDeleteCmdExe;
import cn.study.luckyapp.activityrule.query.ActivityRuleByParamQueryExe;
import cn.study.luckyapp.award.command.AwardAddCmdExe;
import cn.study.luckyapp.award.command.AwardUpdateCmdExe;
import cn.study.luckyapp.award.query.AwardListByParamQueryExe;
import cn.study.luckyapp.listener.event.ActivityCreateEvent;
import cn.study.luckyapp.rule.command.RuleAddCmdExe;
import cn.study.luckyapp.rule.command.RuleUpdateCmdExe;
import cn.study.luckyapp.rule.query.RuleListByParamQueryExe;
import cn.study.luckyclient.api.IActivityConfigService;
import cn.study.luckyclient.dto.*;
import cn.study.luckyclient.dto.data.*;
import cn.study.luckyclient.dto.query.ActivityListByParamQuery;
import cn.study.luckyclient.dto.query.ActivityRuleByParamQuery;
import cn.study.luckyclient.dto.query.AwardListByParamQuery;
import cn.study.luckyclient.dto.query.RuleListByParamQuery;
import cn.study.luckyinfrastructure.gateway.iml.dataObject.ActivityRuleDB;
import com.baomidou.mybatisplus.core.metadata.IPage;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.event.ApplicationContextEvent;
import org.springframework.context.event.ApplicationEventMulticaster;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
@AllArgsConstructor
@Slf4j
public class ActivityConfigServiceImpl implements IActivityConfigService {
    private final ActivityAddCmdExe activityAddCmdExe;
    private final AwardAddCmdExe awardAddCmdExe;
    private final ActivityRuleAddCmdExe activityRuleAddCmdExe;

    private ActivityUpdateCmdExe activityUpdateCmdExe;
    private AwardUpdateCmdExe awardUpdateCmdExe;
    private ActivityRuleDeleteCmdExe activityRuleDeleteCmdExe;

    private ActivityListByParamQueryExe activityListByParamQueryExe;
    private ActivityRuleByParamQueryExe activityRuleByParamQueryExe;
    private RuleListByParamQueryExe ruleListByParamQueryExe;
    private AwardListByParamQueryExe awardListByParamQueryExe;

    private final ApplicationEventMulticaster applicationEventMulticaster;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public ActivityConfigVo add(ActivityConfigAddCmd cmd) {
        ActivityVo activityVo = activityAddCmdExe.execute(cmd.getActivityAddCmd());
        List<RuleVo> ruleVos = addActivityRule(cmd.getRuleIdList(), activityVo);


        List<AwardVo> awardVos=addAwardVo(cmd.getAwardAddCmd(),activityVo);

        ActivityConfigVo activityConfigVo = new ActivityConfigVo();
        activityConfigVo.setActivityVo(activityVo);
        activityConfigVo.setRuleVoList(ruleVos);
        activityConfigVo.setAwardVo(awardVos);

        //发送活动创建事件
        applicationEventMulticaster.multicastEvent(new ActivityCreateEvent("",activityConfigVo));

        return activityConfigVo;
    }

    private List<AwardVo> addAwardVo(List<AwardAddCmd> awardAddCmdList, ActivityVo activityVo) {
        AssertUtil.isTrue(CollectionUtil.isEmpty(awardAddCmdList), "奖项不为空！");

        List<AwardVo> result = new ArrayList<>();
        for (AwardAddCmd awardAddCmd : awardAddCmdList) {
            awardAddCmd.setActivityId(activityVo.getId());
            result.add(awardAddCmdExe.execute(awardAddCmd));
        }

        return result;
    }

    private List<RuleVo> addActivityRule(List<Long> ruleIdList, ActivityVo activityVo) {

        ArrayList<ActivityRuleAddCmd> cmdList= new ArrayList<>();
        for(Long ruleId:ruleIdList){
            ActivityRuleAddCmd activityRuleAddCmd = new ActivityRuleAddCmd();
            activityRuleAddCmd.setActivityId(activityVo.getId());
            activityRuleAddCmd.setRuleId(ruleId);
            cmdList.add(activityRuleAddCmd);
        }
        List<ActivityRuleVo> activityRuleVoList= activityRuleAddCmdExe.execute(cmdList);
        List<Long> ids= new ArrayList<>();
        for(ActivityRuleVo activityRuleVo:activityRuleVoList){
            ids.add(activityRuleVo.getRuleId());
        }
        RuleListByParamQuery ruleListByParamQuery = new RuleListByParamQuery();
        ruleListByParamQuery.setIds(ids);
       return ruleListByParamQueryExe.execute(ruleListByParamQuery).getRecords();
    }

    @Override
    public ActivityConfigVo update(ActivityConfigUpdateCmd cmd) {
        ActivityVo activityVo=activityUpdateCmdExe.execute(cmd.getActivityUpdateCmd());
        activityRuleDeleteCmdExe.execute(activityVo.getId());
        List<RuleVo> ruleVos = addActivityRule(cmd.getRuleIdList(), activityVo);

        List<AwardVo> awardVos=updateAward(cmd.getAwardUpdateCmd(),activityVo);

        ActivityConfigVo activityConfigVo = new ActivityConfigVo();
        activityConfigVo.setActivityVo(activityVo);
        activityConfigVo.setRuleVoList(ruleVos);
        activityConfigVo.setAwardVo(awardVos);
        return activityConfigVo;
    }

    private List<AwardVo> updateAward(List<AwardUpdateCmd> awardUpdateCmdList, ActivityVo activityVo) {
        AssertUtil.isTrue(CollectionUtil.isEmpty(awardUpdateCmdList), "奖项不为空！");

        List<AwardVo> result = new ArrayList<>();
        for (AwardUpdateCmd awardUpdateCmd : awardUpdateCmdList) {
            result.add(awardUpdateCmdExe.execute(awardUpdateCmd));
        }

        return result;
    }

    @Override
    public ActivityConfigVo one(Long id) {
        ActivityListByParamQuery activityListByParamQuery = new ActivityListByParamQuery();
        activityListByParamQuery.setId(id);
        List<ActivityVo> activityVOList= activityListByParamQueryExe.execute(activityListByParamQuery).getRecords();
        AssertUtil.isTrue(CollectionUtil.isEmpty(activityVOList), "数据不存在！");
        ActivityVo activityVO = activityVOList.get(0);
        final var activityRuleListByParamQuery = new ActivityRuleByParamQuery();
        activityRuleListByParamQuery.setActivityId(activityVO.getId());
        List<ActivityRuleVo> activityRuleVOList = activityRuleByParamQueryExe.execute(activityRuleListByParamQuery);
        List<RuleVo> ruleVOList = getRuleVOList(activityRuleVOList.stream().map(ActivityRuleVo::getRuleId).collect(Collectors.toList()));

        AwardListByParamQuery awardListByParamQuery = new AwardListByParamQuery();
        awardListByParamQuery.setActivityId(activityVO.getId());
        awardListByParamQuery.setPageSize(1000);
        List<AwardVo> awardVOList = awardListByParamQueryExe.execute(awardListByParamQuery).getRecords();


        ActivityConfigVo activityConfigVO = new ActivityConfigVo();
        activityConfigVO.setActivityVo(activityVO);
        activityConfigVO.setRuleVoList(ruleVOList);
        activityConfigVO.setAwardVo(awardVOList);
        return activityConfigVO;
    }
    private List<RuleVo> getRuleVOList(List<Long> ruleIdList){
        RuleListByParamQuery query = new RuleListByParamQuery();
        query.setIds(ruleIdList);
        query.setPageSize(1000);

        return ruleListByParamQueryExe.execute(query).getRecords();
    }
}
